#include "Python.h"
#include <wiringPi.h>

static PyObject* pyfunc_GPIO_init(PyObject* self,PyObject* args){
    if(wiringPiSetupPhys()<0){
        return NULL;
    };
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject* pyfunc_GPIO_cleanup(PyObject* self,PyObject* args){
    int pin;
    if(!PyArg_ParseTuple(args,"i",&pin)) {
        return NULL;
    };
    pinMode(pin,INPUT);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject* pyfunc_GPIO_setup(PyObject* self,PyObject* args){
    int pin,mode;
    if(!PyArg_ParseTuple(args,"ii",&pin,&mode)) {
        return NULL;
    };
    if(mode!=1 && mode!=0){
        return NULL;
    };
    pinMode(pin,!mode);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject* pyfunc_GPIO_input(PyObject* self,PyObject* args){
    int pin,val;
    if(!PyArg_ParseTuple(args,"i",&pin)) {
        return NULL;
    };
    val=digitalRead(pin);
    return Py_BuildValue("i",val);
}

static PyObject* pyfunc_GPIO_output(PyObject* self,PyObject* args){
    int pin,val;
    if(!PyArg_ParseTuple(args,"ii",&pin,&val)) {
        return NULL;
    };
    if(val!=1 && val!=0){
        return NULL;
    };
    digitalWrite(pin,val);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyObject* pyfunc_GPIO_delaymicroseconds(PyObject* self,PyObject* args){
    int time;
    if(!PyArg_ParseTuple(args,"i",&time)) {
        return NULL;
    };
    delayMicroseconds(time);
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef module_methods[]={
    {"init",pyfunc_GPIO_init,METH_VARARGS,NULL},
    {"cleanup",pyfunc_GPIO_init,METH_VARARGS,NULL},
    {"setup",pyfunc_GPIO_setup,METH_VARARGS,NULL},
    {"input",pyfunc_GPIO_input,METH_VARARGS,NULL},
    {"output",pyfunc_GPIO_output,METH_VARARGS,NULL},
    {"delayMicroseconds",pyfunc_GPIO_delaymicroseconds,METH_VARARGS,NULL},
    {NULL,NULL,0,NULL}
};

#if PY_MAJOR_VERSION > 2
static struct PyModuleDef GPIO_module={
    PyModuleDef_HEAD_INIT,
    "GPIO",
    NULL,
    -1,
    module_methods
};
#endif

#if PY_MAJOR_VERSION > 2
PyMODINIT_FUNC PyInit_GPIO(void)
#else
PyMODINIT_FUNC initGPIO(void)
#endif
{
    #if PY_MAJOR_VERSION > 2
        PyObject* module=PyModule_Create(&GPIO_module);
    #else
        PyObject* module=Py_InitModule("GPIO",module_methods);
    #endif
    PyModule_AddObject(module,"HIGH",Py_BuildValue("i",1));
    PyModule_AddObject(module,"LOW",Py_BuildValue("i",0));
    PyModule_AddObject(module,"IN",Py_BuildValue("i",1));
    PyModule_AddObject(module,"OUT",Py_BuildValue("i",0));
    #if PY_MAJOR_VERSION > 2
        return module;
    #else
        return;
    #endif
}